package org.spring.bean.factory.support;

import org.spring.bean.exceptions.BeanDefinitionStoreException;
import org.spring.bean.factory.config.BeanDefinition;
import org.tool.TipException;

/**
 * 包含 bean 定义的注册表的接口，例如 RootBeanDefinition 和 ChildBeanDefinition 实例。
 * 通常由内部使用 AbstractBeanDefinition 层次结构的 BeanFactories 实现。
 *
 * <p>这是 Spring 的 bean factory 包中唯一封装 <i>registration<i> bean 定义的接口。
 * 标准 BeanFactory 接口仅涵盖对<i>完全配置的工厂实例<i>的访问。
 *
 * <p>Spring 的 bean 定义读者期望在这个接口的实现上工作。
 * Spring 核心中的已知实现者是 DefaultListableBeanFactory 和 GenericApplicationContext。
 *
 * @author 李坤
 * @date 2022/4/20 21:45
 */
public interface BeanDefinitionRegistry {

    /**
     * 返回给定bean名称的BeanDefinition。
     *
     * @param beanName 要查找其定义的bean的名称
     *
     * @return 给定名称的BeanDefinition(不要使用 { @ code null })
     *
     * @throws TipException 如果没有这样的bean定义
     */
    BeanDefinition getBeanDefinition(String beanName) throws TipException;

    /**
     * 使用此注册表注册一个新的 bean 定义。
     * 必须支持 RootBeanDefinition 和 ChildBeanDefinition。
     *
     * @param beanName       要注册的 bean 实例的名称
     * @param beanDefinition 要注册的 bean 实例的定义
     *
     * @throws BeanDefinitionStoreException    如果 BeanDefinition 无效
     * @throws BeanDefinitionOverrideException 如果已经有指定 bean 名称的 BeanDefinition 并且我们不允许覆盖它
     */
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;

    /**
     * 返回注册中心中定义的bean的数量。
     *
     * @return 注册中心中定义的bean的数量
     */
    int getBeanDefinitionCount();

    /**
     * 确定给定的bean名是否已经在该注册中心中使用，即是否有一个本地bean或别名在该名称下注册。
     *
     * @param beanName 要检查的名字
     *
     * @return 给定的bean名是否已经被使用
     */
    boolean isBeanNameInUse(String beanName);

    /**
     * 检查该注册表是否包含具有给定名称的bean定义。
     *
     * @param beanName 要查找的bean的名称
     *
     * @return 如果该注册表包含具有给定名称的bean定义
     */
    boolean containsBeanDefinition(String beanName);

}
